﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace System.Linq
{
    /// <summary>
    /// String扩展
    /// </summary>
    public static class StringExtension
    {
        /// <summary>
        /// 截取字符串，超出部分以省略符号代替
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="omitString">省略符号</param>
        /// <param name="stringLength">截取长度，包含省略符号</param>
        /// <returns></returns>
        public static string SubText(this string obj, string omitString = "...", int stringLength = 10)
        {
            if (obj.Length <= stringLength) return obj;
            if (obj.Length + omitString.Length <= stringLength) return obj + omitString;

            return obj.Substring(0, stringLength - omitString.Length - 1) + omitString;
        }

        /// <summary>
        /// 定长字符串，不够长的字符串回居中，左右以replaceString填充
        /// </summary>
        /// <param name="obj">源字符串</param>
        /// <param name="stringLength">定长长度</param>
        /// <param name="replaceString">填充字符</param>
        /// <returns></returns>
        public static string FixLength(this string obj, int stringLength = 76, char replaceString = '=')
        {
            if (obj.Length > stringLength) return obj;

            var length = (stringLength - obj.Length) / 2;
            var newString = "".PadLeft(length, replaceString) + obj + "".PadRight(length, replaceString);

            if (newString.Length < stringLength) newString = newString + "".PadRight(stringLength - newString.Length, replaceString);

            return newString;
        }

        /// <summary>
        /// 等同于string.Format
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static string FormatString(this string obj, params object[] args)
        {
            return string.Format(obj, args);
        }

        /// <summary>
        /// 截断尾部
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="endStr">截断字符</param>
        /// <returns></returns>
        public static string TrimEnd(this string obj, string endStr)
        {
            if (obj.IsNull()) return string.Empty;
            if (endStr.IsNull()) return obj;
            if (!obj.EndsWith(endStr)) return obj;

            return obj.Substring(0, obj.Length - endStr.Length);
        }

        /// <summary>
        /// 截断头部
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="startStr">截断字符</param>
        /// <returns></returns>
        public static string TrimStart(this string obj, string startStr)
        {
            if (obj.IsNull()) return string.Empty;
            if (startStr.IsNull()) return obj;
            if (!obj.StartsWith(startStr)) return obj;

            return obj.Substring(startStr.Length);
        }

        /// <summary>
        /// Json字符反序列化为对象
        /// </summary>
        /// <typeparam name="TSource">对象类型</typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static TSource ToJsonObject<TSource>(this string obj)
        {
            try
            {
                return Newtonsoft.Json.JsonConvert.DeserializeObject<TSource>(obj);
            }
            catch
            {
                return default(TSource);
            }
        }


        public static bool IsNullOrEmpty(this string s)
        {
            return string.IsNullOrEmpty(s);
        }
        public static string ConvertString(this string data)
        {
            if (data == null)
            {
                return "";
            }
            else
            {
                return data;
            }
        }



        public static int ToInt(this string value)
        {
            return Int32.Parse(value);
        }



        public static int ToInt(this string value, int defaultValue)
        {
            var result = defaultValue;
            return int.TryParse(value, out result) ? result : defaultValue;
        }

        public static int? ToNullableInt(this string value)
        {
            int result;

            if (string.IsNullOrEmpty(value) || !int.TryParse(value, out result))
            {
                return null;
            }

            return result;
        }

        public static decimal ToDecimal(this string value)
        {
            return decimal.Parse(value);
        }

        public static decimal ToDecimal(this string value, decimal defaultValue)
        {
            var result = defaultValue;
            return decimal.TryParse(value, out result) ? result : defaultValue;
        }

        public static decimal ToRoundDecimal(this string value, decimal defaultValue, int decimals)
        {
            var result = defaultValue;
            result = Math.Round(decimal.TryParse(value, out result) ? result : defaultValue, decimals);
            return result;
        }


        public static decimal? ToNullableDecimal(this string value)
        {
            decimal result;
            if (string.IsNullOrEmpty(value) || !decimal.TryParse(value, out result))
            {
                return null;
            }
            return result;
        }

        public static short? ToNullableShort(this string value)
        {
            short result;

            if (string.IsNullOrEmpty(value) || !short.TryParse(value, out result))
            {
                return null;
            }

            return result;
        }

        public static DateTime? ToNullableDateTime(this string value)
        {
            DateTime result;

            if (DateTime.TryParse(value, out result))
            {
                return result;
            }

            return null;
        }

        public static DateTime ToDateTime(this string value)
        {
            return DateTime.Parse(value);
        }

        public static byte? ToNullableByte(this string value)
        {
            byte result;

            if (string.IsNullOrEmpty(value) || !byte.TryParse(value, out result))
            {
                return null;
            }

            return result;
        }


        public static bool? ToNullableBool(this string value)
        {
            bool result;

            if (string.IsNullOrEmpty(value) || !bool.TryParse(value, out result))
            {
                return null;
            }

            return result;
        }

        public static bool ToBool(this string value)
        {
            return bool.Parse(value);
        }

    }
}
